package cz.muni.fi.pa165.rentalofconstructionmachineryweb.controller;

import cz.muni.fi.pa165.rentalofconstructionmachinery.dto.MachineDTO;
import cz.muni.fi.pa165.rentalofconstructionmachinery.dto.RentalDTO;
import cz.muni.fi.pa165.rentalofconstructionmachinery.dto.RevisionDTO;
import cz.muni.fi.pa165.rentalofconstructionmachinery.service.MachineService;
import cz.muni.fi.pa165.rentalofconstructionmachinery.service.RentalService;
import cz.muni.fi.pa165.rentalofconstructionmachinery.service.RevisionService;
import java.util.Collections;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

@Controller
@RequestMapping("/machine")
public class MachineController {
    
    private MachineService machineService;
    private RentalService rentalService;
    private RevisionService revisionService;
    
    @RequestMapping("")
    public String list(Model model) {
        model.addAttribute("machines", machineService.listMachines());
        return "machine";
    }
    
    @RequestMapping(value = "/{id}/details", method = RequestMethod.GET)
    public String getDetails(@PathVariable Long id, Model model) {
        if(null == id) {
            return "redirect:/machine?error&msg=Machine Id not provided";
        } else {
            MachineDTO machine = machineService.searchForMachineById(id);
            if(null == machine) {
                return "redirect:/machine?error&msg=Machine with given Id doesn't exist";
            } else {
                model.addAttribute("machine", machine);

                List<RentalDTO> rentals = rentalService.getRentalsByMachine(machine);
                model.addAttribute("rentals", rentals);
                
                List<RevisionDTO> revisions = revisionService.getAllRevisionsOfMachine(machine);
                model.addAttribute("revisions", revisions);
                
                if(0 != revisions.size()) {
                    RevisionDTO lastRevision = revisionService.getLastRevisionOfMachine(machine);
                    model.addAttribute("lastRevision", Collections.singletonList(lastRevision));
                } else {
                    model.addAttribute("lastRevision", null);
                }
                
                return "machineDetails";
            }
        }
    }
    
    @RequestMapping(value = "/new", method = RequestMethod.GET)
    public String getNew(Model model) {
        return "machineForm";
    }
    
    @RequestMapping(value = "/new", method = RequestMethod.POST)
    public String postNew(@RequestParam("licensePlate") String licensePlate, @RequestParam("type") String type, Model model) {
        if(null == licensePlate || 0 == licensePlate.length() || null == type || 0 == type.length()) {
            return "redirect:/machine?error&msg=Some fields not correctly populated";
        } else {
            MachineDTO existingMachine = machineService.searchForMachineByPlate(licensePlate);
            if(null != existingMachine) {
                return "redirect:/machine?error&msg=Machine with given plates already exists";
            } else {
                MachineDTO machine = new MachineDTO(null, licensePlate, type);
                machineService.addMachine(machine);
                return "redirect:/machine?success";
            }
        }
    }
    
    @RequestMapping(value = "/{id}/edit", method = RequestMethod.GET)
    public String getEdit(@PathVariable Long id, Model model) {
        if(null == id) {
            return "redirect:/machine?error&msg=Machine Id not provided";
        } else {
            MachineDTO machine = machineService.searchForMachineById(id);
            if(null == machine) {
                return "redirect:/machine?error&msg=Machine with given Id doesn't exist";
            } else {
                model.addAttribute("licensePlate", machine.getLicensePlate());
                model.addAttribute("type", machine.getType());
                return "machineForm";
            }
        }
    }
    
    @RequestMapping(value = "/{id}/edit", method = {RequestMethod.POST, RequestMethod.PUT})
    public String postEdit(@PathVariable Long id, @RequestParam("licensePlate") String licensePlate, @RequestParam("type") String type, Model model) {
        if(null == licensePlate || 0 == licensePlate.length() || null == type || 0 == type.length() || null == id) {
            return "redirect:/machine?error&msg=Some fields not correctly populated";
        }  else {
            MachineDTO machine = machineService.searchForMachineById(id);
            if(null == machine) {
                return "redirect:/machine?error&msg=Machine with given Id doesn't exist";
            } else {
                machine.setLicensePlate(licensePlate);
                machine.setType(type);
                machineService.modifyMachine(machine);
                return "redirect:/machine?success";
            }
        }
    }
    
    @RequestMapping(value = "/{id}/delete", method = {RequestMethod.GET, RequestMethod.DELETE})
    public String delete(@PathVariable Long id, Model model) {
        if(null == id) {
            return "redirect:/machine?error&msg=Machine Id not provided";
        } else {
            MachineDTO machine = machineService.searchForMachineById(id);
            if(null == machine) {
                return "redirect:/machine?error&msg=Machine with given Id doesn't exist";
            } else {
                for(RentalDTO rental : rentalService.getRentalsByMachine(machine)) rentalService.removeRental(rental);
                for(RevisionDTO revision : revisionService.getAllRevisionsOfMachine(machine)) revisionService.delete(revision);
                machineService.removeMachine(machine);
                return "redirect:/machine?success";
            }
        }
    }
    
    @Autowired
    public MachineController(MachineService machineService, RevisionService revisionService, RentalService rentalService) {
        this.machineService = machineService;
        this.rentalService = rentalService;
        this.revisionService = revisionService;
    }
    
}